package com.easylive.utils;

import com.easylive.entity.config.AppConfig;
import com.easylive.entity.constants.Constants;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;

/**
 * @Author: yudaxian
 * @DateTime: 2024/11/5 22:13
 **/
@Component
public class FFmpegUtils {

    @Resource
    private AppConfig appConfig;

    public void createImageThumbnail(String filePath) {
        /**
         * 生成缩略图命令：
         * ffmpeg -i input.jpg -vf scale=200:-1 output.jpg
         */
        String CMD = "ffmpeg -i \"%s\" -vf scale=200:-1 \"%s\"";
        /**
         * %s 代表输入文件路径，%s 代表输出文件路径
         */
        CMD = String.format(CMD, filePath, filePath + Constants.IMAGE_THUMBNAIL_SUFFIX);
        /**
         * 用这个工具类执行命令，显示执行日志
         */
        ProcessUtils.executeCommand(CMD, appConfig.getShowFfmpegLog());
    }

    /**
     * 获取视频时长
     * @param completeVideo
     */
    public Integer getVideoInfoDuration(String completeVideo) {
        final String CMD_GET_CODE = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \"%s\"";
        String cmd = String.format(CMD_GET_CODE, completeVideo);
        String result = ProcessUtils.executeCommand(cmd, appConfig.getShowFfmpegLog());
        if (StringTools.isEmpty(result)) {
            return 0;
        }
        // 去除换行部分
        result = result.replace("\n", "");
        // 转换为整数
        return new BigDecimal(result).intValue();
    }

    /**
     * 获取视频编码格式, 如 h264, hevc, h264才是需要的，是mp4
     * @param videoFilePath
     * @return
     */
    public String getVideoCodec(String videoFilePath) {
        final String CMD_GET_CODE = "ffprobe -v error -select_streams v:0 -show_entries stream=codec_name \"%s\"";
        String result = ProcessUtils.executeCommand(String.format(CMD_GET_CODE, videoFilePath), appConfig.getShowFfmpegLog());
        result.replace("\n", "");
        result = result.substring(result.indexOf("=") + 1);
        String codec = result.substring(0, result.indexOf("["));
        return codec;
    }

    /**
     * 转换视频编码格式为h264
     * @param newFileName
     * @param videoFilePath
     */
    public void convertHevc2Mp4(String newFileName, String videoFilePath) {
        String CMD_HEVC_264 = "ffmpeg -i \"%s\" -c:v libx264 -crf 20 \"%s\" -y";
        String cmd = String.format(CMD_HEVC_264, newFileName, videoFilePath);
        ProcessUtils.executeCommand(cmd, appConfig.getShowFfmpegLog());
    }

    /**
     * 比如说有一个 1.mp4 文件，第一步先将这个文件转换成 index.ts 文件
     * 根据时长切割成多个ts文件，并且生成索引文件.m3u8
     * @param tsFolder
     * @param videoFilePath
     */
    public void convertVideo2Ts(File tsFolder, String videoFilePath) {
        final String CMD_TRANSFER_2TS = "ffmpeg -y -i \"%s\" -vcodec copy -acodec copy -bsf:v h264_mp4toannexb \"%s\"";
        final String CMD_CUT_TS = "ffmpeg -i \"%s\" -c copy -map 0 -f segment -segment_list \"%s\" -segment_time 10 %s/%%4d.ts";
        String tsPath = tsFolder + "/" + Constants.TS_NAME;
        // 生成 .ts
        String cmd = String.format(CMD_TRANSFER_2TS, videoFilePath, tsPath);
        ProcessUtils.executeCommand(cmd, appConfig.getShowFfmpegLog());
        // 生成索引文件.m3u8 和 切片.ts
        cmd = String.format(CMD_CUT_TS, tsPath, tsFolder.getPath() + "/" + Constants.M3U8_NAME, tsFolder.getPath());
        ProcessUtils.executeCommand(cmd, appConfig.getShowFfmpegLog());
        // 删除index.ts
        new File(tsPath).delete();
    }
}
